package nagel_schreckenberg;

import java.util.ArrayList;

public class Lane {
	
	private ArrayList<Vehicle> v;
	private Intersection source;
	private Intersection target;
	private int length;
	private int speedlimit;
	private boolean open;
	
	public enum Direction{
		NORTH, EAST, SOUTH, WEST, MAIN, MINOR, NONE;
	}
	private Direction dir;
	
	public enum Type{
		IN, OUT;
	}
	private Type type;

	public enum Occupation{
		EMPTY, REGULAR, FULL;
	}
	private Occupation occupation;
	
	public Lane(int l, int s){
		v = new ArrayList<Vehicle>();
		length = l;
		speedlimit = s;
		dir = Direction.NONE;
		open = true;
	}
	
	public void connectSource(Intersection i){
		source = i;
	}
	
	public Intersection getSource(){
		return source;
	}
	
	public void connectTarget(Intersection i){
		target = i;
	}
	
	public Intersection getTarget(){
		return target;
	}
	
	public Direction getDirection(){
		return dir;
	}
	
	public void setDirection(Direction d){
		dir = d;
	}
	
	public Type getType(){
		return type;
	}
	
	public void setType(Type t){
		type = t;
	}
	
	public int getLength(){
		return length;
	}
	
	public int distToNextVehicle(int pos){
		int distance = 0;
		if(pos!=0){
			distance = v.get(pos-1).getPosition()-v.get(pos).getPosition();
		}
		else{
			if(target.getOut(dir).getVehicles().isEmpty()){
				distance = length - v.get(pos).getPosition() + target.getOut(dir).getLength();
				if(!open){
					distance = length - v.get(pos).getPosition();
				}
			}
			else{
				distance = length - v.get(pos).getPosition() + target.getOut(dir).getVehicles().get(target.getOut(dir).getVehicles().size()-1).getPosition();
				if(!open){
					distance = length - v.get(pos).getPosition();
				}
			}
		}
		return distance;
	}
	
	public int getSpeedLimit(){
		return speedlimit;
	}
	
	public void setSpeedLimit(int s){
		speedlimit = s;
	}
	
	public ArrayList<Vehicle> getVehicles(){
		return v;
	}
	
	public void addVehicle(Vehicle n){
		v.add(n);
	}
	
	public Vehicle removeVehicle(int pos){
		Vehicle n = v.get(pos);
		v.remove(pos);
		return n;
	}
	
	public void green(){
		open = true;
	}
	
	public void red(){
		open = false;
	}
	
	public boolean getPhase(){
		return open;
	}
	
	public int getWaitingCars(){
		int counter = 0;
		for(Vehicle vh : v){
			if(vh.isWaiting()){
				counter++;
			}
		}
		return counter;
	}

	public int waitingWithin(int d){
		int ww = 0;
		for(int i = 0; i < v.size(); i++){
			if(length - v.get(i).getPosition() < d){
				ww++;
			}
			else{
				break;
			}
		}
		return ww;
	}

	public Occupation getOccupation(){
		return occupation;
	}
	
	public void setOccupation(){
		if(v.size()/(double)length <= Config.OCCUPATION_ER){
			occupation = Occupation.EMPTY;
		}
		else if(v.size()/(double)length > Config.OCCUPATION_ER && v.size()/(double)length < Config.OCCUPATION_RF){
			occupation = Occupation.REGULAR;
		}
		else{
			occupation = Occupation.FULL;
		}
	}
}
